package com.scau.RBAC.service.impl;

import com.scau.RBAC.dao.factory.DaoFactory;
import com.scau.RBAC.dao.factory.DaoFactoryProducer;
import com.scau.RBAC.dao.UserDao;
import com.scau.RBAC.dao.RoleDao;
import com.scau.RBAC.dao.UserRoleDao;
import com.scau.RBAC.model.entity.User;
import com.scau.RBAC.model.entity.Role;
import com.scau.RBAC.model.entity.UserRole;
import com.scau.RBAC.service.UserService;
import com.scau.RBAC.exception.BusinessException;
import com.scau.RBAC.exception.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户服务实现类，实现用户管理的业务逻辑
 */
@Service
public class UserServiceImpl implements UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    private final DaoFactory daoFactory;
    private final UserDao userDao;
    private final RoleDao roleDao;
    private final UserRoleDao userRoleDao;

    public UserServiceImpl() {
        // 使用DAO工厂生产类获取DAO工厂实例
        this.daoFactory = DaoFactoryProducer.getDaoFactory();
        // 通过DAO工厂获取具体的DAO实例
        this.userDao = daoFactory.getUserDao();
        this.roleDao = daoFactory.getRoleDao();
        this.userRoleDao = daoFactory.getUserRoleDao();
        logger.info("UserServiceImpl初始化完成");
    }

    @Override
    public User authenticateUser(String username, String password) {
        try {
            logger.info("用户认证: {}", username);

            // 参数验证
            if (username == null || password == null || username.isEmpty() || password.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户名或密码不能为空");
            }

            // 根据用户名查询用户
            User user = userDao.findByUsername(username);
            if (user == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 密码验证（实际应用中应使用加密验证）
            if (!Objects.equals(user.getPassword(), password)) {
                throw new BusinessException(ErrorCode.INVALID_CREDENTIALS, "密码错误");
            }

            // 检查用户状态
            if (user.getStatus() != 1) {
                throw new BusinessException(ErrorCode.USER_DISABLED, "用户已被禁用");
            }

            // 更新最后登录时间
            user.setLastLoginTime(LocalDateTime.now());
            userDao.update(user);

            logger.info("用户认证成功: {}", username);
            return user;
        } catch (BusinessException e) {
            logger.error("用户认证失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("用户认证异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户认证服务异常", e);
        }
    }

    @Override
    public void logoutUser(Long userId) {
        try {
            logger.info("用户登出: {}", userId);
            // 此处可添加登出逻辑，如清除会话等
        } catch (Exception e) {
            logger.error("用户登出异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户登出服务异常", e);
        }
    }

    @Override
    public User createUser(User user) {
        try {
            logger.info("创建用户: {}", user.getUsername());

            // 参数验证
            if (user == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户信息不能为空");
            }

            // 检查用户名是否已存在
            if (userDao.findByUsername(user.getUsername()) != null) {
                throw new BusinessException(ErrorCode.USERNAME_EXISTS, "用户名已存在");
            }

            // 设置创建和更新时间
            LocalDateTime now = LocalDateTime.now();
            user.setCreatedTime(now);
            user.setUpdatedTime(now);

            // 插入用户数据
            userDao.insert(user);
            logger.info("用户创建成功: {}", user.getUsername());
            return user;
        } catch (BusinessException e) {
            logger.error("创建用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("创建用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户创建服务异常", e);
        }
    }

    @Override
    public void updateUser(User user) {
        try {
            logger.info("更新用户: {}", user.getId());

            // 参数验证
            if (user == null || user.getId() == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID不能为空");
            }

            // 检查用户是否存在
            if (userDao.findById(user.getId()) == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 更新时间
            user.setUpdatedTime(LocalDateTime.now());

            // 更新用户数据
            userDao.update(user);
            logger.info("用户更新成功: {}", user.getId());
        } catch (BusinessException e) {
            logger.error("更新用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("更新用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户更新服务异常", e);
        }
    }

    @Override
    public void deleteUser(Long userId) {
        try {
            logger.info("删除用户: {}", userId);

            // 参数验证
            if (userId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID不能为空");
            }

            // 检查用户是否存在
            if (userDao.findById(userId) == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 删除用户角色关联
            userRoleDao.deleteByUserId(userId);

            // 删除用户
            userDao.deleteById(userId);
            logger.info("用户删除成功: {}", userId);
        } catch (BusinessException e) {
            logger.error("删除用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("删除用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户删除服务异常", e);
        }
    }

    @Override
    public User getUserById(Long userId) {
        try {
            logger.info("获取用户信息: {}", userId);

            // 参数验证
            if (userId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID不能为空");
            }

            User user = userDao.findById(userId);
            if (user == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            return user;
        } catch (BusinessException e) {
            logger.error("获取用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取用户服务异常", e);
        }
    }

    @Override
    public User getUserByUsername(String username) {
        try {
            logger.info("根据用户名获取用户: {}", username);

            // 参数验证
            if (username == null || username.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户名不能为空");
            }

            User user = userDao.findByUsername(username);
            if (user == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            return user;
        } catch (BusinessException e) {
            logger.error("获取用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取用户服务异常", e);
        }
    }

    @Override
    public List<User> getAllUsers() {
        try {
            logger.info("获取所有用户");
            return userDao.findAll();
        } catch (Exception e) {
            logger.error("获取所有用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取所有用户服务异常", e);
        }
    }

    @Override
    public List<User> getUsersByCondition(User condition) {
        try {
            logger.info("根据条件查询用户");
            // 实际应用中可能需要更复杂的条件查询逻辑
            return new ArrayList<>();
        } catch (Exception e) {
            logger.error("条件查询用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "条件查询用户服务异常", e);
        }
    }

    @Override
    public void assignRoleToUser(Long userId, String roleCode) {
        try {
            logger.info("为用户分配角色: userId={}, roleCode={}", userId, roleCode);

            // 参数验证
            if (userId == null || roleCode == null || roleCode.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID和角色代码不能为空");
            }

            // 检查用户是否存在
            if (userDao.findById(userId) == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 检查角色是否存在
            Role role = roleDao.findByRoleCode(roleCode);
            if (role == null) {
                throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在");
            }

            // 检查用户是否已拥有该角色
            List<Role> userRoles = roleDao.findByUserId(userId);
            for (Role r : userRoles) {
                if (Objects.equals(r.getId(), role.getId())) {
                    throw new BusinessException(ErrorCode.PARAM_ERROR, "用户已拥有该角色");
                }
            }

            // 创建用户角色关联
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(role.getId());
            userRole.setCreatedTime(LocalDateTime.now());
            userRole.setCreatedBy(Long.valueOf("system")); // 可以根据实际情况设置创建者

            userRoleDao.insert(userRole);
            logger.info("角色分配成功: userId={}, roleId={}", userId, role.getId());
        } catch (BusinessException e) {
            logger.error("分配角色失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("分配角色异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分配角色服务异常", e);
        }
    }

    @Override
    public void removeRoleFromUser(Long userId, String roleCode) {
        try {
            logger.info("移除用户角色: userId={}, roleCode={}", userId, roleCode);

            // 参数验证
            if (userId == null || roleCode == null || roleCode.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID和角色代码不能为空");
            }

            // 查找角色
            Role role = roleDao.findByRoleCode(roleCode);
            if (role == null) {
                throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在");
            }

            // 检查用户是否拥有该角色
            boolean hasRole = false;
            List<Role> userRoles = roleDao.findByUserId(userId);
            for (Role r : userRoles) {
                if (Objects.equals(r.getId(), role.getId())) {
                    hasRole = true;
                    break;
                }
            }

            if (!hasRole) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户未拥有该角色");
            }

            // 由于UserRoleDao没有根据userId和roleId删除的方法，我们使用自定义方式
            // 这里通过查询所有用户角色，然后删除对应的关联
            try {
                // 由于我们没有findByUserIdAndRoleId方法，这里需要使用原生SQL或其他方式
                // 但根据BaseDao的限制，我们可以通过创建临时的UserRole对象并设置userId和roleId来处理
                // 注意：实际使用时可能需要修改UserRoleDao实现以支持这种删除方式
                // 或者在UserRoleDao中添加新的deleteByUserIdAndRoleId方法

                // 这里我们使用一种变通方法：获取用户的所有角色，然后重新保存除了要删除的角色之外的所有角色
                List<Role> remainingRoles = new ArrayList<>();
                for (Role r : userRoles) {
                    if (!Objects.equals(r.getId(), role.getId())) {
                        remainingRoles.add(r);
                    }
                }

                // 先删除所有用户角色关联
                userRoleDao.deleteByUserId(userId);

                // 重新添加除了要删除的角色之外的所有角色
                for (Role r : remainingRoles) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(r.getId());
                    userRole.setCreatedTime(LocalDateTime.now());
                    userRole.setCreatedBy(Long.valueOf("system"));
                    userRoleDao.insert(userRole);
                }

                logger.info("角色移除成功: userId={}, roleId={}", userId, role.getId());
            } catch (Exception e) {
                logger.error("删除用户角色关联失败", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "删除用户角色关联失败", e);
            }
        } catch (BusinessException e) {
            logger.error("移除角色失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("移除角色异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "移除角色服务异常", e);
        }
    }

    @Override
    public void updateUserRoles(Long userId, List<String> roleCodes) {
        try {
            logger.info("更新用户角色: userId={}, roles={}", userId, roleCodes);

            // 参数验证
            if (userId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID不能为空");
            }

            // 检查用户是否存在
            if (userDao.findById(userId) == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 先删除所有现有角色
            userRoleDao.deleteByUserId(userId);

            // 如果角色列表不为空，重新分配角色
            if (roleCodes != null && !roleCodes.isEmpty()) {
                for (String roleCode : roleCodes) {
                    // 检查角色是否存在
                    Role role = roleDao.findByRoleCode(roleCode);
                    if (role == null) {
                        throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在: " + roleCode);
                    }

                    // 创建用户角色关联
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(role.getId());
                    userRole.setCreatedTime(LocalDateTime.now());
                    userRole.setCreatedBy(Long.valueOf("system"));
                    userRoleDao.insert(userRole);
                }
            }

            logger.info("用户角色更新成功: userId={}", userId);
        } catch (BusinessException e) {
            logger.error("更新用户角色失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("更新用户角色异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新用户角色服务异常", e);
        }
    }

    @Override
    public List<Role> getUserRoles(Long userId) {
        try {
            logger.info("获取用户角色: {}", userId);

            // 参数验证
            if (userId == null) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID不能为空");
            }

            // 检查用户是否存在
            if (userDao.findById(userId) == null) {
                throw new BusinessException(ErrorCode.USER_NOT_FOUND, "用户不存在");
            }

            // 使用RoleDao的findByUserId方法直接获取用户的角色列表
            return roleDao.findByUserId(userId);
        } catch (BusinessException e) {
            logger.error("获取用户角色失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取用户角色异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取用户角色服务异常", e);
        }
    }

    @Override
    public List<User> getUsersByRole(String roleCode) {
        try {
            logger.info("根据角色获取用户: {}", roleCode);

            // 参数验证
            if (roleCode == null || roleCode.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "角色代码不能为空");
            }

            // 查找角色
            Role role = roleDao.findByRoleCode(roleCode);
            if (role == null) {
                throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在");
            }

            // 获取用户列表
            return userDao.findByRoleId(role.getId());
        } catch (BusinessException e) {
            logger.error("获取用户列表失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("获取用户列表异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "获取用户列表服务异常", e);
        }
    }

    @Override
    public void batchCreateUsers(List<User> users) {
        try {
            logger.info("批量创建用户: {}", users.size());

            // 参数验证
            if (users == null || users.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户列表不能为空");
            }

            // 批量插入用户
            userDao.batchInsert(users);
            logger.info("批量创建用户成功");
        } catch (BusinessException e) {
            logger.error("批量创建用户失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("批量创建用户异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "批量创建用户服务异常", e);
        }
    }

    @Override
    public void batchAssignRoles(Long userId, List<String> roleCodes) {
        try {
            logger.info("批量分配角色: userId={}, roles={}", userId, roleCodes);

            // 参数验证
            if (userId == null || roleCodes == null || roleCodes.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID和角色代码列表不能为空");
            }

            // 获取用户当前的角色
            List<Role> currentRoles = roleDao.findByUserId(userId);
            Set<Long> currentRoleIds = new HashSet<>();
            for (Role role : currentRoles) {
                currentRoleIds.add(role.getId());
            }

            // 逐个分配角色
            for (String roleCode : roleCodes) {
                try {
                    // 检查角色是否存在
                    Role role = roleDao.findByRoleCode(roleCode);
                    if (role == null) {
                        throw new BusinessException(ErrorCode.ROLE_NOT_FOUND, "角色不存在: " + roleCode);
                    }

                    // 检查用户是否已拥有该角色
                    if (!currentRoleIds.contains(role.getId())) {
                        UserRole userRole = new UserRole();
                        userRole.setUserId(userId);
                        userRole.setRoleId(role.getId());
                        userRole.setCreatedTime(LocalDateTime.now());
                        userRole.setCreatedBy(Long.valueOf("system"));
                        userRoleDao.insert(userRole);
                    }
                } catch (BusinessException e) {
                    throw e; // 重新抛出异常，确保错误信息能够正确传递
                }
            }

            logger.info("批量分配角色成功: userId={}", userId);
        } catch (BusinessException e) {
            logger.error("批量分配角色失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("批量分配角色异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "批量分配角色服务异常", e);
        }
    }

    @Override
    public void batchUpdateUserStatus(List<Long> userIds, boolean status) {
        try {
            logger.info("批量更新用户状态: {}", userIds.size());

            // 参数验证
            if (userIds == null || userIds.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户ID列表不能为空");
            }

            // 逐个更新用户状态
            for (Long userId : userIds) {
                User user = userDao.findById(userId);
                if (user != null) {
                    user.setStatus(status ? 1 : 0);
                    user.setUpdatedTime(LocalDateTime.now());
                    userDao.update(user);
                }
            }

            logger.info("批量更新用户状态成功");
        } catch (Exception e) {
            logger.error("批量更新用户状态异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "批量更新用户状态服务异常", e);
        }
    }
}